import { judgeType } from "@/utils/judge";
import { TableOptions } from "./types";
import { createDBFn } from "@/utils/decorate";
import Big from "big.js";

// 把驼峰转换成横杠连接
export const toLine = (value: string) => {
  return value.replace(/(A-Z)g/, "-$1").toLocaleLowerCase();
};

export const renderLoadTime = 100;
export const getWidth = (item) => {
  if (item?.width) {
    if (judgeType("string", item.width)) {
      return Number(item.width.replace("px", ""));
    } else {
      return item.width;
    }
  }
  return 0;
};

const resolveConfig = (tableOption, config) => {
  // 有些是计算属性computed 需要拿到接口后才能拿到 所以 暂定1200
  // const totalWidth = tableOption.reduce((prev, cur) => {
  //   let curWidth = 0
  //   if(cur?.width) {
  //     curWidth = Number(cur.width.replace('px', ''))
  //   }
  //   return prev + curWidth
  // },0)
  // if (window.innerWidth > 1200 && config?.noWidth) {
  //   tableOption.forEach((item) => {
  //     if (!item.noWidth) {
  //       item.width = undefined
  //     }
  //   })
  // }
  const {
    computeWidth,
    extraWidthList,
    computeWidthChange,
    allWrap,
    wrapList,
    noWidthList = [],
    allWrapIgnoreList = [],
    computePropList = [],
    noComputePropList = [],
  } = config || {};

  const allWrapDeal = (allWrap, item) => {
    if (!allWrap) return;
    allWrapIgnoreList.push(...["operate"]);
    if (allWrapIgnoreList.includes(item.prop)) return;
    const propertyList = ["dictAttrs", "formatter", "slot"];
    const flag = propertyList.some((a) => item[a]);
    if (flag) return;

    item.slot = item.prop;
    item.wrap = true;
    if (item.noWidth) {
      item.width = "180px";
    }
  };

  const wrapListDeal = (wrapList, item) => {
    if (!wrapList?.length) return;
    if (wrapList.includes(item.prop)) {
      item.slot = item.prop;
      item.wrap = true;
      if (item.noWidth) {
        item.width = "180px";
      }
    }
  };

  const noWidthListDeal = (noWidthList, item) => {
    if (!noWidthList?.length) return;
    if (noWidthList.includes(item.prop)) {
      item.width = undefined;
    }
  };

  const scaleComputeWidth = (item) => {
    const scale = 20;
    const len = item.label.length;
    if (len <= 4) {
      item.width = scale * len + 20;
      return;
    }
    item.width = scale * len + 5;
  };

  // 默认20px 1字符
  const computePropListWidth = (computePropList, item) => {
    if (!computePropList?.length) return;
    const flag = computePropList.includes(item.prop) && item.noWidth;
    if (flag) {
      scaleComputeWidth(item);
    }
  };

  const noComputePropListWidth = (noComputePropList, item) => {
    if (!noComputePropList?.length) return;
    const ignoreList = ["Time", "operate"];
    const everyIgnore = ignoreList.every((a) => !item.prop.includes(a));
    // 手动设置宽度不计算-自动设置的宽度才进行计算
    const flag = !noComputePropList.includes(item.prop) && everyIgnore && item.noWidth;
    if (flag) {
      scaleComputeWidth(item);
    }
  };

  // 动态计算填充宽度-给没有设置宽度的进行填充
  const computeWidthDeal = (tableOption, computeWidth, extraWidthList, computeWidthChange?) => {
    if (!computeWidth) return;
    let extraWidth = 0;
    const tableOptionWidth = tableOption.reduce((prev, cur) => {
      return prev + getWidth(cur);
    }, 0);
    if (extraWidthList) {
      extraWidthList.forEach((item) => {
        extraWidth += item.width;
      });
    }

    const assignWidth = (tableOptionWidth, extraWidth) => {
      // const tableBodDom = document.querySelector('#list-box')
      // if (!tableBodDom) return
      // const padding = 20
      // const tableBoxDomWidth = tableBodDom.clientWidth - padding * 2

      const tableBodDom = document.querySelector("#SmTable");
      if (!tableBodDom) return;
      const tableBoxDomWidth = tableBodDom.clientWidth;

      // 需要分配的数量
      const assignNum = tableOption.reduce((prev, cur) => {
        if (cur?.noWidth) {
          return prev + 1;
        }
        return prev;
      }, 0);

      const averageWidth = Number(
        Big((tableBoxDomWidth - tableOptionWidth - extraWidth) / assignNum).toFixed(2)
      );

      if (tableBoxDomWidth < tableOptionWidth) return;

      tableOption.forEach((item) => {
        if (item.noWidth) {
          item.width = averageWidth + getWidth(item) + "px";
        }
      });
      // computeWidthChange && computeWidthChange()
    };

    setTimeout(() => {
      try {
        assignWidth(tableOptionWidth, extraWidth);
      } catch (e) {
        console.log("宽度计算错误", e);
      }
    }, renderLoadTime);
  };

  tableOption.forEach((item) => {
    allWrapDeal(allWrap, item);
    wrapListDeal(wrapList, item);
    noWidthListDeal(noWidthList, item);
    computePropListWidth(computePropList, item);
    noComputePropListWidth(noComputePropList, item);
  });

  // 将width转化成min-width
  const resolveTable = () => {
    /**
     * 这里用min-width代替 width
     * 可能会和齿轮设置的冲突
     * min-width和width哪一个优先级高？width实际测试
     * 和SmTableField-min-Width保存配合使用
     * 后面统一用minWidth单位处理-这里统一处理历史遗留问题
     */
    tableOption.forEach((item) => {
      if (item.minWidth) {
        delete item.width;
        return;
      }
      if (item.width) {
        item.minWidth = item.width;
        delete item.width;
      }
    });
  };

  resolveTable();

  // 好像只会初始化监听一次
  // const watchTable = () => {
  //   let flag = false
  //   const computeWidthDealDB = createDBFn(() =>
  //     computeWidthDeal(tableOption, computeWidth, extraWidthList, computeWidthChange)
  //   )
  //   setTimeout(() => {
  //     // 内部执行防抖无效
  //     const observer = new ResizeObserver((entries) => {
  //       if (flag) {
  //         computeWidthDealDB()
  //       }
  //       flag = true
  //     })
  //     const elementToObserve = document.querySelector('#SmTable') as any
  //     if (!elementToObserve) return
  //     observer.observe(elementToObserve)
  //   }, 1000)
  // }

  // if (computeWidth) {
  //   computeWidthDeal(tableOption, computeWidth, extraWidthList, computeWidthChange)
  //   // watchTable()
  // }
};

export const transformTableOptions = (
  fieldMap: { [key: string]: any },
  config?: { [key: string]: any }
) => {
  const tableOption: Array<TableOptions> = [];

  for (const key in fieldMap) {
    const obj: TableOptions = {
      prop: key,
      label: fieldMap[key],
      align: "center",
      width: "100px",
    };
    if (fieldMap[key] instanceof Object) {
      if (!fieldMap[key].width) {
        obj.noWidth = true;
      }

      // if (fieldMap[key].formatter && !fieldMap[key].hideSort) {
      //   obj.sortable = true
      // }
      // 只能对时间字段-时间戳进行排序
      const timeList = ["Time", "Date"];
      const timeFlag = timeList.some((a) => key.includes(a));
      if (timeFlag && !fieldMap[key].hideSort) {
        obj.sortable = true;
      }
      Object.assign(obj, fieldMap[key]);
    } else {
      obj.noWidth = true;
    }
    tableOption.push(obj);
  }
  resolveConfig(tableOption, config);

  return tableOption;
};

export const capitalize = (str) => {
  if (!str) return "";
  return str.charAt(0).toUpperCase() + str.slice(1);
};

export const assignItem = (item: { [key: string]: any }, parentItem, itemKey: string) => {
  for (const key in item) {
    // key首字母大写
    // parentItem[itemKey + key[0].toUpperCase() + key.slice(1)] = item[key]
    parentItem[itemKey + capitalize(key)] = item[key];
  }
};

export const getItemProp = (list: any[], itemKeyList: string[]) => {
  list.forEach((item) => {
    itemKeyList.forEach((key) => {
      const targetItem = item[key];
      if (!targetItem) return;
      assignItem(targetItem, item, key);
    });
  });
  return list;
};

export const transformCapitalizeList = (item: any, prop: string, keyList: string[]) => {
  if (!item[prop]) return;
  try {
    keyList.forEach((key) => {
      const val = item[prop][key];
      item[prop + capitalize(key)] = val;
    });
  } catch (e) {
    console.log(e, `报错了${prop}`);
  }
};

export const getItemPropList = (list: any[], propList: any[]) => {
  try {
    list.forEach((item) => {
      propList.forEach((propItem) => {
        const { prop, keyList } = propItem;
        // 取出list[prop]中keyList对应属性 转化成首字母大写
        transformCapitalizeList(item, prop, keyList);
      });
    });
    return list;
  } catch (e) {
    console.log(e, "报错了");
  }
};

export const useTableData = () => {
  const tableOptions = ref<TableOptions[]>([]);
  const allTableOptions = ref<TableOptions[]>([]);

  return {
    allTableOptions,
    tableOptions,
    transformTableOptions,
    getItemProp,
    getItemPropList,
  };
};
